﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using doubanloginDll8;
using System.Xml;
using System.Drawing.Imaging;

namespace MimiDouban.Extention
{
    /// <summary>
    /// 用于生成音乐基因名片的类
    /// </summary>
    public class MusicGeneGenerator
    {
        private static MusicGeneGenerator uniqueInstance;
        private static readonly int WIDTH = 400;

        /// <summary>
        /// 背景画刷
        /// </summary>
        private Brush backgroundbrush;    

        /// <summary>
        /// 标题所用画刷
        /// </summary>
        private Brush usernamebrush;
        private Brush blackbrush;
        private Brush titleBack;
        private Font titlefont;

        /// <summary>
        /// 基因所用画刷
        /// </summary>
        private Brush[] geneBrushes;
        private Font[] geneFonts;
        private MusicGeneGenerator()
        {

            backgroundbrush = new SolidBrush(Color.White);//背景画刷   
            usernamebrush = new SolidBrush(Color.Blue); //用户名画刷               
            blackbrush = new SolidBrush(Color.Black);//黑色画刷
            titleBack = new SolidBrush(Color.Cornsilk);//标题背景
            titlefont = new Font("宋体", 10);//标题字体

            //基因画刷
            geneBrushes = new Brush[7];
            geneBrushes[0] = new SolidBrush(Color.Blue);
            geneBrushes[1] = new SolidBrush(Color.DeepSkyBlue);
            geneBrushes[2] = new SolidBrush(Color.DodgerBlue);
            geneBrushes[3] = new SolidBrush(Color.DarkSlateBlue);
            geneBrushes[4] = new SolidBrush(Color.DeepSkyBlue);
            geneBrushes[5] = new SolidBrush(Color.DarkBlue);
            geneBrushes[6] = new SolidBrush(Color.DarkBlue);

            //基因字体
            geneFonts = new Font[7];
            geneFonts[0] = new Font("宋体", 10);
            geneFonts[1] = new Font("宋体", 12);
            geneFonts[2] = new Font("宋体", 14);
            geneFonts[3] = new Font("宋体", 16);
            geneFonts[4] = new Font("宋体", 18);
            geneFonts[5] = new Font("宋体", 20);
            geneFonts[6] = new Font("宋体", 22);


        }

        public static MusicGeneGenerator getInstance()
        {
            if (uniqueInstance == null)
            {
                uniqueInstance = new MusicGeneGenerator();
            }
            return uniqueInstance;
        }

        public Bitmap getMusicGene()
        {
            string html = HttpWebResponseUtility.getInstance().CreateGetHttpResponse("http://douban.fm/musicgene");
            Gene[] genes = getGenes(html);
            string username = getUserName(html);


            Bitmap bmp = new Bitmap(WIDTH, WIDTH * 2, PixelFormat.Format24bppRgb);
            Bitmap result = null;
            Graphics g = Graphics.FromImage(bmp);

            //填充背景
            g.FillRectangle(backgroundbrush, new Rectangle(0, 0, WIDTH, WIDTH * 2));

            //标题背景            
            g.FillRectangle(titleBack, new Rectangle(0, 0, WIDTH, 25));
            try
            {

                //画Title
                SizeF usernameSize = g.MeasureString(username, titlefont);
                g.DrawString(username, titlefont, usernamebrush, 5, 5);
                g.DrawString("的音乐基因名片", titlefont, blackbrush, 5 + usernameSize.Width, 5);

                //画基因
                float curX = 0;
                float curY = 30;
                float maxHeightThisLine = 0;
                for (int i = 0; i < genes.Length; i++)
                {
                    SizeF thisSize = g.MeasureString(genes[i].Text, geneFonts[genes[i].Font]);

                    if (thisSize.Width > WIDTH - curX)//如果这一行没有空位了，就换行
                    {
                        curY += maxHeightThisLine;
                        maxHeightThisLine = 0;
                        curX = 0;
                    }

                    if (thisSize.Height > maxHeightThisLine)
                    {
                        maxHeightThisLine = thisSize.Height;
                    }
                    g.DrawString(genes[i].Text, geneFonts[genes[i].Font], geneBrushes[genes[i].Font], curX, curY);
                    curX += thisSize.Width;
                }

                //画边框
                g.DrawRectangle(new Pen(backgroundbrush, 3), new Rectangle(0, 0, WIDTH, Convert.ToInt32(curY+maxHeightThisLine)));
                result = KiCut(bmp, 0, 0, WIDTH, Convert.ToInt32(curY + maxHeightThisLine));                
            }
            finally
            {
                g.Dispose();
                bmp.Dispose();
            }
            return result;
        }

        private Gene[] getGenes(string html)
        {
            Gene[] result;
            try
            {
                int divStart = html.IndexOf("<div class=\"gene-border\">");
                int divEnd = html.IndexOf("</div>", divStart) + "</div>".Length;
                string strDiv = html.Substring(divStart, divEnd - divStart);
                strDiv = strDiv.Replace("<br>", "");
                strDiv = strDiv.Replace("&nbsp;", "");
                strDiv = strDiv.Replace("\n","");
                XmlDocument divDoc = new XmlDocument();
                divDoc.LoadXml(strDiv);
                XmlNodeList spans = divDoc.GetElementsByTagName("span");
                result = new Gene[spans.Count];
                int count = 0;
                foreach (XmlNode s in spans)
                {
                    result[count] = new Gene();
                    result[count].Font = Int32.Parse(s.Attributes["class"].Value.Substring(5));
                    XmlNode a = s.FirstChild;
                    result[count].Url = a.Attributes["href"].Value;
                    result[count].Text = a.InnerText.Trim();
                    count++;
                }
            }
            catch(Exception e)
            {
                result = new Gene[] { };
            }

            return result;
        }

        private string getUserName(string html)
        {
            try
            {
                int startIndex = html.IndexOf("<a href=\"http://www.douban.com/people/");
                startIndex = html.IndexOf('>', startIndex) + 1;
                int endIndex = html.IndexOf('<', startIndex);
                return html.Substring(startIndex, endIndex - startIndex);
            }
            catch
            {
                return "未知用户";
            }
        }

        /// <summary>
        /// 剪裁 -- 用GDI+
        /// </summary>
        /// <param name="b">原始Bitmap</param>
        /// <param name="StartX">开始坐标X</param>
        /// <param name="StartY">开始坐标Y</param>
        /// <param name="iWidth">宽度</param>
        /// <param name="iHeight">高度</param>
        /// <returns>剪裁后的Bitmap</returns>
        private static Bitmap KiCut(Bitmap b, int StartX, int StartY, int iWidth, int iHeight)
        {
            if (b == null)
            {
                return null;
            }

            int w = b.Width;
            int h = b.Height;

            if (StartX >= w || StartY >= h)
            {
                return null;
            }

            if (StartX + iWidth > w)
            {
                iWidth = w - StartX;
            }

            if (StartY + iHeight > h)
            {
                iHeight = h - StartY;
            }

            try
            {
                Bitmap bmpOut = new Bitmap(iWidth, iHeight, PixelFormat.Format24bppRgb);

                Graphics g = Graphics.FromImage(bmpOut);
                g.DrawImage(b, new Rectangle(0, 0, iWidth, iHeight), new Rectangle(StartX, StartY, iWidth, iHeight), GraphicsUnit.Pixel);
                g.Dispose();

                return bmpOut;
            }
            catch
            {
                return null;
            }
        }


    }
}